#include "TestSuite.h"
#include <iostream>

template <typename Func, typename PrintFunc, typename... Args>
TestCase makeTestCase(std::string name, Func func, PrintFunc printFunc, std::tuple<Args...> args)
{
    return TestCase(
        name,
        [func, args](const std::tuple<> &) -> bool
        {
            auto result = func(args);
            // auto result = std::apply(func, args);
            auto t2 = std::make_tuple(result);
            auto t3 = std::tuple_cat(args, t2);

            std::cout << "new tuple : ";
            std::apply([](const auto &...t3)
                       { ((std::cout << t3 << " "), ...); }, t3);
            std::cout << std::endl;
            return result;
        },
        [printFunc, args](const std::tuple<> &, const bool &result)
        {
            printFunc(args, result);
            // std::apply(printFunc, args, result);
        });
}

bool testFunction1(const std::tuple<int, int, double> &args)
{
    std::cout << "testFunction1 Input parameters: ";
    std::apply([](const auto &...args)
               { ((std::cout << args << " "), ...); }, args);
    std::cout << std::endl;
    // int d = a + b + c;
    return true;
}
void printData1(const std::tuple<int, int, double> &args, const bool &result)
{
    std::cout << "printData1 Input parameters: ";
    std::apply([](const auto &...args)
               { ((std::cout << args << " "), ...); }, args);
    std::cout << std::endl;
    std::cout << "testFunction1 Output result: " << result << std::endl;
}

bool testFunction2(const std::tuple<std::string, double> &args)
{
    std::cout << "testFunction2 Input parameters: ";
    std::apply([](const auto &...args)
               { ((std::cout << args << " "), ...); }, args);
    std::cout << std::endl;
    return true;
}
void printData2(const std::tuple<std::string, double> &args, const bool &result)
{
    std::cout << "printData2 Input parameters: ";
    std::apply([](const auto &...args)
               { ((std::cout << args << " "), ...); }, args);
    std::cout << std::endl;

    std::cout << "testFunction2 Output result: " << result << std::endl;
}
int main()
{
    TestSuite suite;

    int c = 20;
    auto args1 = std::make_tuple(c, 10, 3.14);
    auto args2 = std::make_tuple("-1", 2.71);
    // auto args3 = std::make_tuple("aaaaa", 90.0);

    suite.addTestCase(makeTestCase("Test 1", testFunction1, printData1, args1));

    suite.addTestCase(makeTestCase("Test 2", testFunction2, printData2, args2));

    suite.runAll();
    return 0;
}